package cuShapes;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import palette.CurrentColor;
import java.lang.Math;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.*;
//import utilities.logging;

import mainWindowSupport.ShapePropTable;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="xmlarrow")
public class Arrow extends PQShape {
	
	@XmlTransient
	private static final long serialVersionUID = 1L;
	@XmlTransient
	private static int nameCount= 0;

	
	/**************************************************************
	 * Implicit value constructor that sets all PQShape variables
	 * 
	 * create arrow.  Both points are at the same point. 
	 **************************************************************/
	public Arrow(Point centerPoint, Color c){
		this(centerPoint, new Point(centerPoint.x+1,centerPoint.y+1), c);
		rect.setLocation(centerPoint);
		//center = new Rectangle();
		//resize = new Rectangle();
		
	}
	
	public Arrow(){
		this(new Point(0, 0), new Point(0, 0), CurrentColor.getInstance());
		rect = new Rectangle(14,14);
		workingRect = rect;
	}
	
	/*******************************************
	 * Main Constructor
	 * 
	 * @param p1 starting Point
	 * @param p2 ending Pint
	 * @param c Color
	 */
	public Arrow(Point p1, Point p2, Color c)
	{
		super();
		name = "Arrow #" + Integer.toString(nameCount);
		nameCount++;
		color = c;
		lines.add(new StraightLine(p1, p2, c));
		rect = new Rectangle(14,14);
		center = new Rectangle();
		resize = new Rectangle();
		
		// Initialize the properties table
		List<String> rows = new ArrayList<String>();
		rows.add("Text");
		/*rows.add("X");
		rows.add("Y");
		rows.add("Length");*/
		rows.add("Color");
		propTable = new ShapePropTable(rows);
	}
	
    public void setStart(Point start){
    	super.setStart(start);
    	lines.get(0).setStart(start);
    	//we only want the rect to cover the head, so 
    	//   you can only change where the arrow points.
    	//   All arrow heads are 14x14.
    	//rect.setLocation(start);
    	workingRect = rect;
    }
    
    public void setEnd(Point end){
    	super.setEnd(end);
    	lines.get(0).setEnd(end);
    	rect.setLocation(end);
    }
       
	public String getShapeClass() {
		return "Arrow";
	}

	public static void resetNames() {
		nameCount = 0;
	}
	
	public int getWidth() {
		return Math.abs(super.lines.get(0).getStart().x - super.lines.get(0).getEnd().x);
	}
	
	public int getHeight() {
		return Math.abs(super.lines.get(0).getStart().y - super.lines.get(0).getEnd().y);
	}

	public void drawToCanvas(Graphics2D g2) {
		super.lines.get(0).drawLine(g2);
		
		Polygon po=new Polygon(); // this is the arrow head
		
		//Takes the arctan of the slope of the line and then uses that to compute the angles the
		//arrow head needs to be at using the cos and sin functions.  Please be careful unless
		//you really like math or you really hate me!  --Chris Walling
		
		double y = lines.get(0).getStart().getY();
		double endY = lines.get(0).getEnd().getY();
		double x = lines.get(0).getStart().getX();
		double endX = lines.get(0).getEnd().getX();
		
		double theta = Math.atan((endY - y)/(endX-x));
		//logging.write(0, "CPW: theta = " + theta + " startX = " + x + " endX = " + endX);
		if((int)endX >= x)
		{
			po.addPoint((int)endX, (int)endY);
			po.addPoint((int)(endX-(15*Math.cos(theta+.5))), (int)(endY-(15*Math.sin(theta+.5))));
			po.addPoint((int)(endX-(10*Math.cos(theta))), (int)(endY-(10*Math.sin(theta))));
			po.addPoint((int)(endX-(15*Math.cos(theta-.5))), (int)(endY-(15*Math.sin(theta-.5))));
			po.addPoint((int)endX, (int)endY);
		}
		else
		{
			po.addPoint((int)endX, (int)endY);
			po.addPoint((int)(endX+(15*Math.cos(theta+.5))), (int)(endY+(15*Math.sin(theta+.5))));
			po.addPoint((int)(endX+(10*Math.cos(theta))), (int)(endY+(10*Math.sin(theta))));
			po.addPoint((int)(endX+(15*Math.cos(theta-.5))), (int)(endY+(15*Math.sin(theta-.5))));
			po.addPoint((int)endX, (int)endY);
		}

		rect.setBounds(po.getBounds());
		g2.fillPolygon(po);
		g2.drawPolygon(po);
		g2.drawString(name, (int)(x+endX)/2 + 15,(int)(y+endY)/2 + 15);
		
	}
	
	
	public void moveWorkingRect(Point p){
		setEnd(p);
		rect.setLocation(p);		
	}

	/***
	 * Tell if our single rect intersects a point.
	 *  
	 */
	public boolean hitRect(Point p) {
		return rect.contains(p);
	
	}

}
